package com.dlc.shop.delivery.api.listener;

import cn.hutool.core.util.StrUtil;
import com.dlc.shop.bean.app.dto.DvyTypeDTO;
import com.dlc.shop.bean.app.dto.ShopCartOrderDto;
import com.dlc.shop.bean.app.dto.ShopCartOrderMergerDto;
import com.dlc.shop.bean.enums.DvyType;
import com.dlc.shop.bean.event.SubmitOrderEvent;
import com.dlc.shop.bean.model.Station;
import com.dlc.shop.bean.model.UserAddrOrder;
import com.dlc.shop.bean.order.SubmitOrderOrder;
import com.dlc.shop.common.config.Constant;
import com.dlc.shop.common.constants.SegmentIdKey;
import com.dlc.shop.common.exception.YamiShopBindException;
import com.dlc.shop.common.util.BeanUtil;
import com.dlc.shop.delivery.common.model.OrderSelfStation;
import com.dlc.shop.delivery.common.service.OrderSelfStationService;
import com.dlc.shop.service.SegmentService;
import com.dlc.shop.service.StationService;
import com.dlc.shop.service.UserAddrOrderService;
import lombok.AllArgsConstructor;
import org.springframework.context.event.EventListener;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 确认订单信息时的默认操作
 *
 * @author LGH
 */
@Component("deliverySubmitOrderListener")
@AllArgsConstructor
public class  SubmitOrderListener {



    private final UserAddrOrderService userAddrOrderService;

    private final StationService stationService;

    private final OrderSelfStationService orderSelfStationService;

    private final SegmentService segmentService;

    private final Integer LENGTH = 8;
    private final Integer ROUND_LENGTH = (LENGTH-2)/2;
    private final Integer INIT_ROUND = 100000;

    /**
     * 订单自提信息处理
     */
    @EventListener(SubmitOrderEvent.class)
    @Order(SubmitOrderOrder.SAME_CITY)
    public void deliverySubmitOrderListener(SubmitOrderEvent event) {
        ShopCartOrderMergerDto mergerOrder = event.getMergerOrder();
        String userId = mergerOrder.getUserId();
        Date now = new Date();
        // 订单商品参数
        List<ShopCartOrderDto> shopCartOrders = mergerOrder.getShopCartOrders();
        // 订单地址id
        Long addrId = null;
        //收件人姓名
        String receiverName = null;
        //收件人手机号码
        String receiverMobile = null;
        Map<Long, Integer> dvyTypeMap = mergerOrder.getDvyTypes().stream().collect(Collectors.toMap(DvyTypeDTO::getShopId, DvyTypeDTO::getDvyType));
        long count = event.getOrders().stream().filter(order -> Objects.isNull(order.getOrderMold()) || order.getOrderMold() == 0).count();
        Set<Integer> dvyTypeSet = mergerOrder.getDvyTypes().stream().map(DvyTypeDTO::getDvyType).collect(Collectors.toSet());
        boolean isAddr = dvyTypeSet.contains(DvyType.DELIVERY.value()) || dvyTypeSet.contains(DvyType.SAME_CITY.value());
        // 不为虚拟商品的快递和同城配送的地址信息
        if (count > 0 && isAddr){
            // 把订单地址保存到数据库
            UserAddrOrder userAddrOrder = BeanUtil.map(mergerOrder.getUserAddr(), UserAddrOrder.class);
            if (userAddrOrder == null) {
                // 请填写收货地址
                throw new YamiShopBindException("yami.delivery.address");
            }
            userAddrOrder.setCreateTime(now);
            userAddrOrder.setUserId(userId);
            userAddrOrderService.save(userAddrOrder);
            addrId = userAddrOrder.getAddrOrderId();
            receiverName = userAddrOrder.getReceiver();
            receiverMobile = userAddrOrder.getMobile();
        }

        //循环订单，插入地址信息
        for (com.dlc.shop.bean.model.Order order:event.getOrders()){
            //自提订单的地址信息
            if (Objects.equals(dvyTypeMap.get(order.getShopId()), DvyType.STATION.value())) {
                OrderSelfStation orderSelfStation = BeanUtil.map(mergerOrder.getOrderSelfStationDto(), OrderSelfStation.class);
                if (orderSelfStation == null) {
                    // 请填写自提信息
                    throw new YamiShopBindException("yami.station.address.check");
                }
                Station station = stationService.getStationInfoById(orderSelfStation.getStationId());
                if (Objects.isNull(station)) {
                    // 自提点信息不存在，请重新选择自提点
                    throw new YamiShopBindException("yami.station.no.exist");
                }
                String addr = station.getProvince() + station.getCity() + station.getArea() + station.getAddr();
                //获取提货码
                String code = Constant.PICKUP_CODE_PREFIX + segmentService.getSegmentCode(SegmentIdKey.STATION, 8);
                orderSelfStation.setStationCode(code);
                orderSelfStation.setOrderNumber(order.getOrderNumber());
                orderSelfStation.setShopId(order.getShopId());
                orderSelfStation.setStationAddress(addr);
                //若是固定电话，则拼接上区号
                String phonePrefix = StrUtil.isNotBlank(station.getPhonePrefix())?station.getPhonePrefix():"";
                orderSelfStation.setStationPhone(phonePrefix + station.getPhone());
                orderSelfStation.setCreateTime(now);
                orderSelfStation.setUpdateTime(now);
                orderSelfStationService.save(orderSelfStation);
                addrId = orderSelfStation.getId();
                receiverName = orderSelfStation.getStationUserName();
                receiverMobile = orderSelfStation.getStationUserMobile();
                order.setDvyId(station.getStationId());
            }
            if (order.getOrderMold() == 0) {
                order.setAddrOrderId(addrId);
                order.setReceiverName(receiverName);
                order.setReceiverMobile(receiverMobile);
            }
        }
    }

    /**
     *  随机码： 三位随机数 + （月+日+45） + 三位随机数
     *  若随机码不够用，可更改长度：LENGTH 和 初始值：INIT_ROUND，增加随机码
     * @param oldCode
     * @return
     */
    private String getCode(String oldCode){
        Calendar cal = Calendar.getInstance();
        int dayAddMonth = (cal.get(Calendar.DATE)) + cal.get(Calendar.MONTH) + 46;
        String code;
        Long roundNum;
        if (StrUtil.isNotBlank(oldCode)){
            //随机数增加的最大值
            Integer changeNum = 5;
            // 获取随机数
            Integer num = Integer.parseInt(oldCode.substring(0,ROUND_LENGTH) + oldCode.substring(LENGTH - ROUND_LENGTH));
            roundNum = num + Math.round(Math.random() * changeNum) + 1;
        }else {
            // 随机数 = 5*100000以内的随机数 + 2*100000
            roundNum = Math.round(Math.random() * 5 * INIT_ROUND) + 2 * INIT_ROUND;
        }
        // 随机数大于等于最大值，初始化
        Long maxRoundNum= 10L * INIT_ROUND;
        if (roundNum >= maxRoundNum){
            roundNum =  roundNum - maxRoundNum + INIT_ROUND;
        }
        code = roundNum.toString();
        return code.substring(0,ROUND_LENGTH)+ dayAddMonth + code.substring(ROUND_LENGTH);
    }
}
